#ifndef OBJECT_HH
# define OBJECT_HH

# include "bounding.hh"
# include "box.hh"
# include "bounding-sphere.hh"
# include <list>

# include "../ai/ai.hh"

# include "phy_const.hh"

# include <math/vector.hh>
# include <math/plane.hh>
# include <interface/sendable.hh>

static const double MOVE_LEFT = 0;
static const double MOVE_RIGHT = 1;
static const double MOVE_UP = 2;
static const double MOVE_DOWN = 3;

// FIXME: Velocity = direction * coef.
// Implement this interface.
class Object: public Sendable
{
public:
  Object (int id, Vector3f pos, Vector3f size, int playerid = 0);
  virtual ~Object ();

  virtual int operator() ();
  void pos_set (const Vector3f& pos);
  const Vector3f& pos_get () const;
  void move (const Vector3f& pos);
  void speed_set (Vector3f speed);
  void speed_add (Vector3f speed);
  Vector3f speed_get ();
  void accel (Vector3f accel);
  void accel_add (Vector3f accel);
  Vector3f accel ();

  void mass (float m);
  float mass ();

  Vector3f direction ();
  void direction (Vector3f direction);

  // FIXME: Function to set speed and direction.
  void new_direction (Vector3f direction);

  // Wrapper of intersect function from bounding forms.
  bool intersect(Object* obj);
  bool intersectWall(Plane& p);

  // Helpful printing for debugging
  void dump ();
  // TODO : Should be virtual after => subclasses
  void receive_message (int msg);
  // Vector3 is not the best for some shapes.
  const Vector3f& size_get () const;

  void update (const Vector3f& newpos);

  void rotate (const Vector3d& rot);
  const Vector3d& rotate () const;

  int id_get ();

  // Return a 16bytes wide string that can directly be sent over the network
  virtual std::string tonet () const;
  std::string tonetupdate () const;

  void posid (int id);
  int posid () const;

  float speed_coef ();
  void speed_coef (float coef);

  int playerid () const { return playerid_; }

  // Get the main bouding box
  Bounding* main_bounding_get ();

protected:
  int id_;
  int posid_;
  int playerid_;
  // FIXME: Change to linear speed.
  Vector3f speed_;
  float mass_;
  Vector3f angular_speed_;
  Vector3f accel_;
  // FIXME: Vector4f to handle different speed for y and x.
  float speed_coef_;
  Vector3f direction_;
  // FIXME: Limit the speed.
  Bounding* main_bounding_;

  // Useless for the moment.
  std::list<Bounding*> extra_boundings_;
};

#endif /// !OBJECT_HH
